package ui;

import java.util.InputMismatchException;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Scanner;

import domein.DomeinController;
import domein.exceptie.SpelbordAlreadyExistsException;

public class ConsoleInterface {
	private int spelbordHoogte, spelbordBreedte;
	private static Locale[] supportedLocales = {
		new Locale("Dutch", "Belgium"), Locale.ENGLISH, Locale.FRENCH };
	private ResourceBundle resourceBundle;
	private Scanner input = new Scanner(System.in);
	
	public ConsoleInterface() {
		
	}
	
	public void start() {
		kiesTaal();
		kiesSpelbord();
		
		String[][] huidigSpelbord = DomeinController.getInstance().geefSpelbord();
		
		spelbordHoogte = huidigSpelbord.length;
		spelbordBreedte = huidigSpelbord[0].length;
		printSpelbord(huidigSpelbord);
		
		System.out.println("\n\n");
		
		maakKeuze();
		
		DomeinController.getInstance().closeConnection();
	}
	
	public void kiesSpelbord() {
		String[][] spelborden = DomeinController.getInstance().geefSpelborden();
		
		System.out.printf("%-3s%-20s%-20s%-20s\n", " ", resourceBundle.getString("naam"),  resourceBundle.getString("breedte"), resourceBundle.getString("hoogte"));
		int teller=1;
		
		for(String[] spelbord:spelborden) {
			System.out.printf("%d. ", teller++);
			
			for(String element:spelbord) {
				System.out.printf("%-20s", element);
			}
			
			System.out.println();
		}
		
		System.out.printf("%d. %s\n",teller, resourceBundle.getString("nieuw"));
		teller++;
		System.out.printf("%d. %s \n\n",teller,resourceBundle.getString("spelbordVerwijderen"));
		
		System.out.printf(resourceBundle.getString("spelbordKiezen"),teller);
		int keuze = this.geefNumeriekeInvoer(1, teller);
		
		if(keuze != teller && keuze != teller-1) {
			DomeinController.getInstance().selecteerSpelbord(spelborden[keuze-1][0]);
		}
		else if(keuze == teller-1){					// aanmaken van een nieuw spelbord
			System.out.println(resourceBundle.getString("spelbordAanmaken"));
			input.nextLine();
			
			System.out.print(resourceBundle.getString("naam") + ": ");
			String naam = input.nextLine();
			
			System.out.print(resourceBundle.getString("breedte") + ": ");
			int breedte = this.geefNumeriekeInvoer(0, 30);
			
			System.out.print(resourceBundle.getString("hoogte") + ": ");
			int hoogte = this.geefNumeriekeInvoer(0, 30);
			
			try {
				DomeinController.getInstance().maakSpelbord(naam, breedte, hoogte);
			} catch (SpelbordAlreadyExistsException e) {
				System.out.println(resourceBundle.getString("spelbordBestaat"));
			}
		}
		else {									// verwijderen van een spelbord
			System.out.println(resourceBundle.getString("spelbordVerwijderenInfo"));
			System.out.printf(resourceBundle.getString("welkSpelbordVerwijderen"), teller-2);
			int bordNr = geefNumeriekeInvoer(1, teller-2);
			
			
			System.out.printf(resourceBundle.getString("bevestigSpelbordVerwijderen"), spelborden[bordNr-1][0]);
			int verificatie = geefNumeriekeInvoer(0,1);
			if(verificatie==0){
				DomeinController.getInstance().verwijderSpelbord(spelborden[bordNr-1][0]);
			}
			kiesSpelbord();
		}
	}
	
	/**
	 * Print het spelbord dat wordt meegegeven
	 * @author Sam Verschueren
	 */
	private void printSpelbord(String[][] spelbord) {
		System.out.println("\n");

		int teller = 1;

		System.out.printf("%4s", "");
		for (int i = 0; i < spelbord[0].length; i++) {
			System.out.printf("%2s", (char) ((int) 'A' + i));
		}

		System.out.printf("\n%2s", "");
		for (int i = 1; i <= spelbord[0].length + 2; i++) {
			System.out.printf("%2s", "+");
		}

		System.out.println();

		for (String[] rij : spelbord) {
			System.out.printf("%-2d%2s", teller++, "+");

			for (String element : rij) {
				System.out.printf("%2s", element);
			}

			System.out.printf("%2s\n", "+");
		}

		System.out.printf("%2s", "");
		for (int i = 1; i <= spelbord[0].length + 2; i++) {
			System.out.printf("%2s", "+");
		}
	}
	
	/**
	 * @author Bart Beyers
	 */
	public void maakKeuze() {
		System.out.println("1. " + resourceBundle.getString("plaatsObstakelSpelbord"));
		System.out.println("2. " + resourceBundle.getString("plaatsPersonageSpelbord"));
		System.out.println("3. " +  resourceBundle.getString("verplaatsBeginpositieSpelbord"));
		System.out.println("4. " +  resourceBundle.getString("verplaatsEindpositieSpelbord"));
		System.out.println("5. " +  resourceBundle.getString("leegmakenVakSpelbord"));
		System.out.println("6. " +  resourceBundle.getString("leveleditorAfsluiten"));
		
		int keuze = geefNumeriekeInvoer(1, 6);
		
		if(keuze == 1) {
			plaatsObstakel();
		}
		else if(keuze == 2){
			plaatsPersonage();
		}
		else if(keuze == 3){
			plaatsBeginPositie();
		}
		else if(keuze == 4){
			plaatsEindPositie();
		}
		else if(keuze == 5){
			verwijderVak();
		}
	}
	

	/**
	 * @author Sam Verschueren
	 */
	private void plaatsObstakel(){
		// Beschikbare obstakels weergeven
		System.out.printf("\n%3s%-20s%-20s\n", "", resourceBundle.getString("obstakel"), resourceBundle.getString("weergave"));
		
		String[][] obstakels = DomeinController.getInstance().geefObstakels();
		
		for(int i=0; i<obstakels.length; i++) {
			System.out.printf("%d. ", i+1);
			
			for(int j=1; j<obstakels[i].length; j++) {
				System.out.printf("%-20s",resourceBundle.getString(obstakels[i][0]));
				System.out.printf("%-20s", obstakels[i][j]);
			}
			
			System.out.println();
		}
		
		// Gebruiker een obstakel laten selecteren
		System.out.printf(resourceBundle.getString("selecteerObstakel"), obstakels.length);
		
		int obstakel = this.geefNumeriekeInvoer(1, obstakels.length);
		
		DomeinController.getInstance().selecteerObstakel(obstakels[obstakel-1][0]);
		
		boolean plaatsObstakel=true;
		
		while(plaatsObstakel) {
			// De gebruiker een rij & kolom laten selecteren
			System.out.printf(resourceBundle.getString("obstakelPlaatsen"), spelbordHoogte);
			int rij = this.geefNumeriekeInvoer(0, spelbordHoogte);
			
			if(rij != 0) {
				System.out.printf(resourceBundle.getString("kolomKiezen"), (char)(spelbordBreedte-1+'A'));
				char kolom = this.geefCharInvoer('A', (char)(spelbordBreedte-1+'1'));
				
				int kol = (int)(kolom-'A');
				
				this.printSpelbord(DomeinController.getInstance().plaats(kol, rij-1));
				
				System.out.println();
			}
			else {
				plaatsObstakel = false;
			}
		}
		
		maakKeuze();
	}
	
	/**
	 * @author Bart Beyers
	 */
	private void plaatsPersonage(){
		// Beschikbare personages weergeven
		String[][] beschikbarePersonages = DomeinController.getInstance().geefPersonageCategorieen();
		
		System.out.printf("\n%3s%-15s%-20s%-20s%-20s%-20s%-3s\n", "", resourceBundle.getString("personage"), resourceBundle.getString("lichaamspunten"), resourceBundle.getString("verdedigingspunten"), resourceBundle.getString("aanvalspunten"), resourceBundle.getString("snelheid"), resourceBundle.getString("weergave"));
		
		for(int i=0;i<beschikbarePersonages.length;i++){
			System.out.printf("%d. %-15s", i+1, resourceBundle.getString(beschikbarePersonages[i][0]));
			
			for(int j=1;j<beschikbarePersonages[0].length-1;j++){
				System.out.printf("%-20s", beschikbarePersonages[i][j]);
			}
			System.out.printf("%-3s\n", beschikbarePersonages[i][0].charAt(0));
		}
		
		// De gebruiker een personage laten selecteren
		System.out.printf("%s (1-%d)",resourceBundle.getString("selecteerPersonage"), beschikbarePersonages.length);
		int invoer = geefNumeriekeInvoer(1, beschikbarePersonages.length);
		
		DomeinController.getInstance().selecteerVijand(beschikbarePersonages[invoer-1][0]);
		
		// Gekozen personage plaatsen
		boolean plaatsPersonage = true;
		
		while(plaatsPersonage){
			// De gebruiker een rij & kolom laten selecteren
			System.out.printf(resourceBundle.getString("rijPersonagePlaatsen"), spelbordHoogte);
			int rij = this.geefNumeriekeInvoer(0, spelbordHoogte);
			
			if(rij != 0) {
				System.out.printf(resourceBundle.getString("kolomKiezen"), (char)(spelbordBreedte-1+'A'));
				char kolom = this.geefCharInvoer('A', (char)(spelbordBreedte-1+'1'));
				
				int kol = (int)(kolom-'A');
				
				this.printSpelbord(DomeinController.getInstance().plaats(kol, rij-1));
				
				System.out.println();
			}
			else {
				plaatsPersonage = false;
			}
		}
		
		maakKeuze();
	}
	
	/**
	 * @author Bart Beyers
	 */
	private void plaatsBeginPositie() {
		// Startpositie selecteren
		DomeinController.getInstance().selecteerStartpositie();
		
		// Coordinaten kiezen
		System.out.println(resourceBundle.getString("kiesCoordsBeginPositie"));
		System.out.printf(resourceBundle.getString("rij"), spelbordHoogte);
		int rij = this.geefNumeriekeInvoer(1, spelbordHoogte);
		
		System.out.printf(resourceBundle.getString("kolom"), (char)(spelbordBreedte-1+'A'));
		char kolom = this.geefCharInvoer('A', (char)(spelbordBreedte-1+'1'));
			
		int kol = (int)(kolom-'A');
			
		// Startpositie plaatsen
		DomeinController.getInstance().plaats(kol, rij-1);
		this.printSpelbord(DomeinController.getInstance().geefSpelbord());
			
		System.out.println();
		maakKeuze();
	}
	
	/**
	 * @author Bart Beyers
	 */
	private void plaatsEindPositie() {
		// Eindpositie selecteren
		DomeinController.getInstance().selecteerEindpositie();
		
		// Coordinaten kiezen
		System.out.println(resourceBundle.getString("kiesCoordsEindPositie"));
		System.out.printf(resourceBundle.getString("rij"), spelbordHoogte);
		int rij = this.geefNumeriekeInvoer(1, spelbordHoogte);
		
		System.out.printf(resourceBundle.getString("kolom"), (char)(spelbordBreedte-1+'A'));
		char kolom = this.geefCharInvoer('A', (char)(spelbordBreedte-1+'1'));

		int kol = (int)(kolom-'A');
		System.out.println(kol);
		// Eindpositie plaatsen
		DomeinController.getInstance().plaats(kol, rij-1);
		this.printSpelbord(DomeinController.getInstance().geefSpelbord());
			
		System.out.println();
	
		maakKeuze();
	}
	
	/**
	 * @author Bart Beyers
	 */
	private void verwijderVak(){
		boolean verwijderVak = true;
		
		while(verwijderVak){
			// De gebruiker een rij & kolom laten selecteren
			System.out.println(resourceBundle.getString(("kiesCoordsVerwijderenObstakel")));
			System.out.printf(resourceBundle.getString("kiesRijObstakelVerwijderen"), spelbordHoogte);
			int rij = this.geefNumeriekeInvoer(0, spelbordHoogte);
			
			if(rij != 0) {
				System.out.printf(resourceBundle.getString("kolom"), (char)(spelbordBreedte-1+'A'));
				char kolom = this.geefCharInvoer('A', (char)(spelbordBreedte-1+'1'));
				
				int kol = (int)(kolom-'A');
				
				DomeinController.getInstance().verwijder(kol, rij-1);
				
				this.printSpelbord(DomeinController.getInstance().geefSpelbord());
				
				System.out.println();
			}
			else {
				verwijderVak = false;
			}
		}
		
		maakKeuze();
	}
	
	/**
	 * Vraagt aan de speler een invoer (getal)
	 * @author Sam Verschueren
	 * @param minInvoer De minimum invoer die de gebruiker mag geven.
	 * @param maxInvoer De maximum invoer die de gebruiker mag geven.
	 * @param allowed Indien de 0-waarde is toegestaan om eventueel te stoppen.
	 */
	private int geefNumeriekeInvoer(int minInvoer, int maxInvoer) {
		boolean geldigeKeuze=false;
		int keuze=0;
		
		do {
			try {
				keuze = input.nextInt();
				
				if(keuze >= minInvoer && keuze <= maxInvoer) {
					geldigeKeuze = true;
				}
				else {
					System.out.println(resourceBundle.getString("geldigeKeuze"));
				}
			}
			catch(InputMismatchException e) {
				System.out.println(resourceBundle.getString("geldigeKeuze"));
			
				input.nextLine();				// Om de keuze uit de input te halen
			}
		} while(!geldigeKeuze);
		
		return keuze;
	}
	
	private char geefCharInvoer(char minInvoer, char maxInvoer) {
		char karakter = input.next().charAt(0);
		
		return karakter;
	}
	
	private void kiesTaal() {
		int keuze;
		int teller = 1;
		resourceBundle = ResourceBundle.getBundle("Labels");

		System.out.println(resourceBundle.getString("kiesTaal"));
		for (Locale e : supportedLocales) {
			System.out.printf("%d. %s\n", (teller++),
					resourceBundle.getString(e.getLanguage()));
		}

		keuze = geefInvoer(1, teller-1);

		resourceBundle = ResourceBundle.getBundle("Labels",
				supportedLocales[keuze - 1]); // De eigenlijke naam van de files
												// is Labels

	}
	
	private int geefInvoer(int minInvoer, int maxInvoer) {
		boolean geldigeKeuze=false;
		int keuze=0;
		
		do {
			try {
				keuze = input.nextInt();
				
				if(keuze >= minInvoer && keuze <= maxInvoer) {
					geldigeKeuze = true;
				}
				else {
					System.out.println(resourceBundle.getString("geldigeKeuze"));
				}
			}
			catch(InputMismatchException e) {
				System.out.println(resourceBundle.getString("geldigeKeuze"));
			
				input = new Scanner(System.in);
			}
		} while(!geldigeKeuze);
		
		return keuze;
	}
	
}
